--- title: "回文日期2" created: 2025-11-28 tags: - 算法 --- # 回文日期2 ## 题目 [回文日期2](https://www.acwing.com/problem/content/2870/) ![[image-7532d8bf.png]] ## 思路分析 本来想套用上一题的做法来的 但是没考虑到很多边界情况 反而弄巧成拙 这种题 还是求稳比较好 先写出一定对的版本 再想优化 一定要保证对! 又改了一个多小时 人麻了 唉 ```cpp #include using namespace std; int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool is_leap(int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } bool check_date(int year, int month, int day) { if (month < 1 || month > 12) return false; int max_day = days[month] + (month == 2 && is_leap(year)); return day >= 1 && day <= max_day; } bool check_format(int year) {//恶心 aaaa不算abab return (year / 100 == year % 100) && (year / 1000 != year / 100 % 10); } int main() { int curyear, curmonth, curday; scanf("%04d%02d%02d", &curyear, &curmonth, &curday); int curdate = curyear * 10000 + curmonth * 100 + curday; int next1 = 0, next2 = 0; for (int year = curyear; !next1; year++) { string yearStr = to_string(year); string rev = yearStr; reverse(rev.begin(), rev.end()); int month = stoi(rev.substr(0, 2)); int day = stoi(rev.substr(2, 2)); if (check_date(year, month, day)) { int date = year * 10000 + month * 100 + day; if (date > curdate) { next1 = date; break; } } } for (int year = curyear; !next2; year++) { if (check_format(year)) { string yearStr = to_string(year); string rev = yearStr; reverse(rev.begin(), rev.end()); int month = stoi(rev.substr(0, 2)); int day = stoi(rev.substr(2, 2)); if (check_date(year, month, day)) { int date = year * 10000 + month * 100 + day; if (date > curdate) { next2 = date; break; } } } } cout << next1 << endl << next2; return 0; } ``` ![[image-fc83ad4a.png]] 这种枚举年份的 有蛮多边界需要注意 要稳健好想的话 可以暴力枚举区间所有数 判断是否是日期 再判断是否是回文日期 再在回文日期的基础上判断是否为abab回文日期 然后优化一点 只枚举这个区间的有效的日期 可以参考日期差那题 找下一个合法日期: `void next_day(int &y,int &m,int &d){` `d++;` `if(d>get_days(y,m)){` `d=1;` `m++;` `if(m>12){` `m=1;` `y++;` `}` `}` `}` ## 代码实现 ```cpp #include using namespace std; int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool is_leap(int y){ return y%100 && y%4==0 || y%400==0; } int get_days(int y,int m){ return days[m]+(m==2 && is_leap(y)); } void next_day(int &y,int &m,int &d){ d++; if(d>get_days(y,m)){ d=1; m++; if(m>12){ m=1; y++; } } } bool check_palindrome(char s[]){ for(int i=0,j=7;i